﻿using Microsoft.Extensions.Logging;
using Syspetro.Core.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Syspetro.Core.EventBus
{
    /// <summary>
    /// 事件处理器容器
    /// </summary>
    public sealed class EventHandlerContainer
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly Dictionary<string, List<Type>> _mappings = new();
        public EventHandlerContainer()
        {
            _serviceProvider = InternalApp.ServicesProvider;
        }
        public static string GetEventKey(Type type, string group)
        {
            return type.FullName + "_" + group;
        }
        public static string GetEventGroup(string key)
        {
            var keys = key.Split("_");
            if (keys.Length >= 2)
                return keys[^1];
            return null;
        }
        /// <summary>
        /// 订阅事件
        /// </summary>
        /// <param name="type"></param>
        /// <param name="typeHandler"></param>
        /// <param name="group"></param>
        public void Subscribe(Type type, Type typeHandler, string group = null)
        {
            var name = GetEventKey(type, group);
            if (!_mappings.ContainsKey(name))
            {
                _mappings.Add(name, new List<Type> { });
            }
            _mappings[name].Add(typeHandler);
        }
        /// <summary>
        /// 订阅事件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="THandler"></typeparam>
        /// <param name="group"></param>
        public void Subscribe<T, THandler>(string group = null) where T : IEventBase where THandler : IEventHandler<T>
        {
            Subscribe(typeof(T), typeof(THandler), group);
        }
        /// <summary>
        /// 取消订阅事件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="THandler"></typeparam>
        public void Unsubscribe<T, THandler>(string group = null) where T : IEventBase where THandler : IEventHandler<T>
        {
            var name = GetEventKey(typeof(T), group);
            _mappings[name].Remove(typeof(THandler));

            if (_mappings[name].Count == 0)
            {
                _mappings.Remove(name);
            }
        }
        #region 发布事件
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <param name="group"></param>
        /// <returns></returns>
        public bool Publish<T>(T o, string group = null) where T : IEventBase
        {
            var name = GetEventKey(typeof(T), group);
            if (_mappings.ContainsKey(name))
            {
                try
                {
                    foreach (var handler in _mappings[name])
                    {
                        var bl = false;
                        var service = _serviceProvider.GetService(handler);
                        var _service = (IEventHandler<T>)service;
                        _service.DataSource = o;
                        bl = _service.Run();
                        if (bl) _service.Callback();
                        o.Finished = true;
                        return bl;
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception($"发布事件{name}失败,{ex.Message}:" + ex.StackTrace);
                }
                finally
                {
                    o.Finished = true;
                }
            }
            return false;
        }
        #endregion
    }
}
